package com.xinqi.modules.homework.homework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinqi.common.core.enums.StudentOperateGroup;
import com.xinqi.common.core.enums.StudentSwitchType;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkEntity;
import com.xinqi.modules.homework.homework.domain.CourseHomeworkStudentLogEntity;
import com.xinqi.modules.homework.homework.mapper.CourseHomeworkMapper;
import com.xinqi.modules.homework.homework.mapper.CourseHomeworkStudentLogMapper;
import com.xinqi.modules.homework.homework.service.CourseHomeworkStudentLogService;
import com.xinqi.modules.homework.homework.service.CourseHomeworkSyncService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 作业学生变动相关操作
 *
 * @author dzy
 */
@Service("homeworkSyncService")
@RequiredArgsConstructor
public class CourseHomeworkSyncServiceImpl implements CourseHomeworkSyncService {

    private final CourseHomeworkStudentLogMapper courseHomeworkStudentLogMapper;

    @Lazy
    private final CourseHomeworkStudentLogService courseHomeworkStudentLogService;

    private final CourseHomeworkMapper courseHomeworkMapper;

    /**
     * 学生加入班级
     */
    @Override
    public void studentJoinClass(Long classId, Long studentId) {
        CourseHomeworkStudentLogEntity entity = new CourseHomeworkStudentLogEntity();
        entity.setClassId(classId);
        entity.setStudentId(studentId);
        this.addRunningHomework(entity);
    }

    /**
     * 成员身份却换事件（学生转助教、助教转学生）
     */
    @Override
    public void studentIdentitySwitch(Long classId, Long studentId, StudentSwitchType switchType) {
        if (switchType == StudentSwitchType.ASSISTANT_TO_STUDENT) {
            CourseHomeworkStudentLogEntity entity = new CourseHomeworkStudentLogEntity();
            entity.setClassId(classId);
            entity.setStudentId(studentId);
            this.addRunningHomework(entity);
        }
    }

    private void addRunningHomework(CourseHomeworkStudentLogEntity entity) {
        // 获取进行中的作业
        List<CourseHomeworkEntity> homeworkEntityList = courseHomeworkStudentLogMapper.findRunningHomework(entity);

        if (CollectionUtils.isEmpty(homeworkEntityList)) {
            return;
        }

        // 获取学生已加入的记录
        List<CourseHomeworkStudentLogEntity> studentList = courseHomeworkStudentLogMapper.findStudentRunningHomework(entity);
        List<CourseHomeworkStudentLogEntity> noHaveHomeworkStudentLogEntityList = this.initNoHaveHomeworkStudentLogEntityList(entity.getClassId(), entity.getStudentId(), homeworkEntityList, studentList);

        if (CollectionUtils.isNotEmpty(noHaveHomeworkStudentLogEntityList)) {
            courseHomeworkStudentLogService.saveBatch(noHaveHomeworkStudentLogEntityList);
        }
    }

    /**
     * 构建没有作业的学生作业列表数据
     *
     * @param studentId          加入班级额学生id
     * @param homeworkEntityList 班级中正在进行的作业列表
     * @param studentList        拥有作业的学生列表
     * @return 没有作业的学生数据模型列表
     */
    private List<CourseHomeworkStudentLogEntity> initNoHaveHomeworkStudentLogEntityList(Long classId, Long studentId, List<CourseHomeworkEntity> homeworkEntityList, List<CourseHomeworkStudentLogEntity> studentList) {
        List<CourseHomeworkStudentLogEntity> studentLogEntityList = new ArrayList<>();
        Map<Long, CourseHomeworkEntity> homeworkEntityMap = homeworkEntityList.stream().collect(Collectors.toMap(CourseHomeworkEntity::getId, v -> v));

        if (CollectionUtils.isEmpty(studentList)) {
            homeworkEntityList.forEach(homeworkEntity -> {
                CourseHomeworkStudentLogEntity studentLogEntity = new CourseHomeworkStudentLogEntity();
                studentLogEntity.setClassId(classId);
                studentLogEntity.setContentId(homeworkEntity.getId());
                studentLogEntity.setStudentId(studentId);
                studentLogEntity.setTimes(homeworkEntity.getRepeatedDay());
                studentLogEntityList.add(studentLogEntity);
            });
        } else {

            Map<Long, List<Long>> studentLogListMap = new HashMap<>();
            studentList.forEach(student -> {
                if (!studentLogListMap.containsKey(student.getContentId())) {
                    List<Long> studentIdList = new ArrayList<>();
                    studentIdList.add(student.getStudentId());
                    studentLogListMap.put(student.getContentId(), studentIdList);
                } else {
                    studentLogListMap.get(student.getContentId()).add(student.getStudentId());
                }
            });

            studentLogListMap.forEach((contentId, studentIdList) -> {
                if (!studentIdList.contains(studentId)) {
                    CourseHomeworkStudentLogEntity studentLogEntity = new CourseHomeworkStudentLogEntity();
                    studentLogEntity.setClassId(classId);
                    studentLogEntity.setContentId(contentId);
                    studentLogEntity.setStudentId(studentId);
                    if (homeworkEntityMap.containsKey(contentId)) {
                        studentLogEntity.setTimes(homeworkEntityMap.get(contentId).getRepeatedDay());
                    }
                    studentLogEntityList.add(studentLogEntity);
                }
            });
        }

        return studentLogEntityList;
    }


    /**
     * 成员加入小组或退出小组
     *
     * @author dzy
     */
    @Override
    public void studentOperateGroup(Long classId, Long studentId, Long groupId, StudentOperateGroup operateGroup) {
        if (Objects.isNull(classId) || Objects.isNull(studentId) || Objects.isNull(groupId)) {
            return;
        }
        // 加入小组才会执行
        if (Objects.equals(StudentOperateGroup.STUDENT_JOIN_GROUP, operateGroup)) {
            // 获取当前小组进行中的小组作业
            List<CourseHomeworkEntity> runningList = courseHomeworkMapper.selectRunningGroupHomework(classId, groupId);
            // 获取学生加入过小组记录
            List<Long> contentIds =
                    runningList.stream().map(CourseHomeworkEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(contentIds) || contentIds.size() == 0) {
                return;
            }
            LambdaQueryWrapper<CourseHomeworkStudentLogEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CourseHomeworkStudentLogEntity::getStudentId, studentId);
            wrapper.in(CourseHomeworkStudentLogEntity::getContentId, contentIds);
            List<CourseHomeworkStudentLogEntity> oldLogList = courseHomeworkStudentLogMapper.selectList(wrapper);
            // 获取不存在的作业日志记录
            Iterator<CourseHomeworkEntity> iterator = runningList.iterator();
            while (iterator.hasNext()) {
                CourseHomeworkEntity item = iterator.next();
                oldLogList.forEach(logItem -> {
                    if (Objects.equals(item.getId(), logItem.getContentId()) && Objects.equals(item.getRepeatDay(),
                            logItem.getTimes())) {
                        iterator.remove();
                    }
                });
            }
            // 生成未入组的学生记录
            List<CourseHomeworkStudentLogEntity> logList = runningList.stream().map(item -> {
                CourseHomeworkStudentLogEntity entity = new CourseHomeworkStudentLogEntity();
                entity.setClassId(classId);
                entity.setStudentId(studentId);
                entity.setContentId(item.getId());
                entity.setTimes(item.getRepeatDay());
                return entity;
            }).collect(Collectors.toList());
            courseHomeworkStudentLogService.saveBatch(logList);
        }
    }

}
